﻿using System;
using System.Collections.Generic;
using FarNet;
using System.Management;

public class procFar : FarNet.ToolPlugin
{
    public override string Name
    {
        get
        {
            return "Process List";
        }
    }

    public override ToolOptions Options
    {
        get
        {
            return ToolOptions.AllAreas;
        }
    }

    private IPluginPanel pluginPanel = null;

    public override void Invoke(object sender, ToolEventArgs e)
    {
        //Far.Msg("Hello " + Name + " " + e.From);
        pluginPanel = Far.CreatePluginPanel();
        pluginPanel.Open();
        pluginPanel.Info.Title = "Process List - KILL'EM ALL!";

        #region commented - havo no idea how to add custom columns in the panel; ideas, anyone?
        /*
        DataItem[] di = new DataItem[2];
        di[0] = new DataItem("XXXA", 1);
        di[1] = new DataItem("XXXB", 2);
        pluginPanel.Info.InfoItems = di;
        */
        #endregion

        pluginPanel.AddDots = true;
        pluginPanel.ViewMode = PanelViewMode.Detailed;
        pluginPanel.IdleUpdate = true;
        pluginPanel.Idled += new EventHandler(pp_Idled);
        pp_Idled(null, null);

    }

    private bool firstRun = true;
    private DateTime lastProcessTimingReading = DateTime.Now;
    private IDictionary<int, KeyValuePair<long, long>> oldProcessesTiming=new Dictionary<int, KeyValuePair<long, long>>();

    void pp_Idled(object sender, EventArgs e)
    {

        TimeSpan timeSpan = DateTime.Now - lastProcessTimingReading;
        lastProcessTimingReading = DateTime.Now;
        
        pluginPanel.Files.Clear();
        if (firstRun)
        {
            firstRun = false;
            IFile f = Far.CreatePanelItem();
            f.Name = "000 First run will report 0 for process load, wait another cycle for accurate results";
            pluginPanel.Files.Add(f);
        }


        System.Management.ManagementObjectSearcher mObjSearcher = new System.Management.ManagementObjectSearcher("Select * from Win32_Process");
        ManagementObjectCollection mObjColl = mObjSearcher.Get();
        
        
        foreach (ManagementBaseObject mBaseObj in mObjColl)
        {
            int pid=Int32.Parse(mBaseObj["ProcessId"].ToString());
            long ktime = Int64.Parse(mBaseObj["KernelModeTime"].ToString());
            long utime = Int64.Parse(mBaseObj["UserModeTime"].ToString());

            if (!oldProcessesTiming.ContainsKey(pid))
            {
                oldProcessesTiming.Add(pid, new KeyValuePair<long, long>(ktime, utime));
            }


            IFile f = Far.CreatePanelItem();
            if (mBaseObj["Name"] != null)
                f.Name = mBaseObj["Name"].ToString();
            else
                f.Name = "?";

            //I want a better precision so I multiply with one more hundred
            //f.Length = 100 * 100 * (ktime - oldProcessesTiming[pid].Key + utime - oldProcessesTiming[pid].Value) / (Environment.ProcessorCount * timeSpan.Ticks);
            f.Length = 100 * (ktime - oldProcessesTiming[pid].Key + utime - oldProcessesTiming[pid].Value) / (Environment.ProcessorCount * timeSpan.Ticks);

            pluginPanel.Files.Add(f);

            oldProcessesTiming[pid] = new KeyValuePair<long, long>(ktime, utime);
        
        }

        

        
        
    }




}

